/*
 * Copyright 2011 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lgcns.android.otmeal;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Handles requests for the application home page.
 * 
 * @author Jiyun Kang
 */
@Controller
@RequestMapping("/*")
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	private static List<Menu> menus;

	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value="/", method=RequestMethod.GET)
	public String home() {
		logger.info("LG CNS OT-Meal ordering system");
		return "home";
	}
	
	/**
	 * Retrieve a list of menus. Accepts a GET request for JSON
	 *  
	 * @return A JSON array of menus
	 */
	@RequestMapping(value="menus", method=RequestMethod.GET, headers="Accept=application/json")
	public @ResponseBody List<Menu> fetchMenusJson() {		
		logger.info("fetching JSON menus");
		return getMenus();
	}
	
	/** 
	 * Retrieve a list of menus. Accepts a GET request for XML
	 *  
	 * @return An XML array of menus
	 */
	@RequestMapping(value="menus", method=RequestMethod.GET, headers="Accept=application/xml")
	public @ResponseBody MenuList fetchMenusXml() {		
		logger.info("fetching XML menus");
		List<Menu> menus = getMenus();
		MenuList menuList = new MenuList(menus);
		return menuList;
	}
	
	/** 
	 * Retrieve a single menu. Accepts a GET request for JSON with a parameter for the menu category
	 * 
	 * @param category
	 * 			contains the menu category to use when finding
	 * 			the corresponding menu
	 * 
	 * @return A JSON menu
	 */
	@RequestMapping(value="menu/{category}", method=RequestMethod.GET, headers="Accept=application/json")
	public @ResponseBody Menu fetchMenuJson(@PathVariable String category) {	
		logger.info("fetching JSON menu");
		return getMenuByCategory(category);
	}
	
	/** 
	 * Retrieve a single menu. Accepts a GET request for XML with a parameter for the menu category
	 * 
	 * @param category
	 * 			contains the menu category to use when finding
	 * 			the corresponding menu
	 * 
	 * @return An XML menu
	 */
	@RequestMapping(value="menu/{category}", method=RequestMethod.GET, headers="Accept=application/xml")
	public @ResponseBody Menu fetchMenuXml(@PathVariable String category) {	
		logger.info("fetching XML menu");
		return getMenuByCategory(category);
	}
	
	/**
	 * Accepts a POST request with a plain text message parameter
	 * 
	 * @param body
	 *           contains the body of the POST request
	 *           
	 * @return a string with the result of the POST
	 */
	@RequestMapping(value="sendmessage", method=RequestMethod.POST, headers="Content-Type=text/plain")
	public @ResponseBody String sendMessage(@RequestBody String message) {
		logger.info("String message: " + message);
		return "String message received! Your message: " + message;
	}
	
	/**
	 * Accepts a POST request with a JSON message parameter
	 * 
	 * @param message
	 *           serialized Message object
	 *           
	 * @return a string with the result of the POST
	 */
	@RequestMapping(value="sendmessage", method=RequestMethod.POST, headers="Content-Type=application/json")
	public @ResponseBody String sendMessageJson(@RequestBody Message message) {
		logger.info("JSON message: " + message.toString());
		return "JSON message received! Your message: " + message.toString();
	}
	
	/**
	 * Accepts a POST request with an XML message parameter
	 * 
	 * @param message
	 *           serialized Message object
	 *           
	 * @return a string with the result of the POST
	 */
	@RequestMapping(value="sendmessage", method=RequestMethod.POST, headers="Content-Type=application/xml")
	public @ResponseBody String sendMessageXml(@RequestBody Message message) {
		logger.info("XML message: " + message.toString());
		return "XML message received! Your message: " + message.toString();
	}
	
	/**
	 * Accepts a POST request with an Map message parameter, and creates a new Message
	 * object from the Map parameters.
	 * 
	 * @param map
	 *           serialized LinkedMultiValueMap<String, String> object
	 *           
	 * @return a string with the result of the POST
	 */
	@RequestMapping(value="sendmessagemap", method=RequestMethod.POST)
	public @ResponseBody String sendMessageMap(@RequestBody LinkedMultiValueMap<String, String> map) {
		Message message = new Message();
		
		try {
			message.setId(Integer.parseInt(map.getFirst("id")));
		} catch (NumberFormatException e) {
			message.setId(0);
		}
		
		message.setSubject(map.getFirst("subject"));
		message.setText(map.getFirst("text"));

		logger.info("Map message: " + message.toString());
		return "Map message received! Your message: " + message.toString();
	}
	
	
	// helper methods
	
	private Menu getMenuByCategory(String category) {
		List<Menu> menus = getMenus();
		
		for (Menu menu : menus) {
			if (menu.getCategory().compareToIgnoreCase(category) == 0) {
				return menu;
			}
		}
		
		return null;
	}
	
	/**
	 * @return a List of menus
	 */
	private List<Menu> getMenus() {
		if (menus == null) {
			menus = new ArrayList<Menu>(); 
			menus.add(new Menu("cheese kimbob", "KR"));
			menus.add(new Menu("고추김밥", "KR"));
			menus.add(new Menu("고추두부찌개", "KR"));
			menus.add(new Menu("bulgoki", "KR"));
			menus.add(new Menu("오삼불고기", "KR"));
			menus.add(new Menu("제육볶음", "KR"));
			menus.add(new Menu("곱돌비빔밥", "KR"));
			menus.add(new Menu("우거지해장국", "KR"));
			menus.add(new Menu("부대찌개", "KR"));
			menus.add(new Menu("고등어조림", "KR"));
			menus.add(new Menu("김치새우볶음밥", "KR"));
			menus.add(new Menu("돈까스", "KR"));
			menus.add(new Menu("전복죽", "KR"));

			menus.add(new Menu("Pizza", "IT"));
			menus.add(new Menu("Pasta", "IT"));
			menus.add(new Menu("spagatti", "IT"));

			menus.add(new Menu("Roll", "JP"));
			menus.add(new Menu("Sushi", "JP"));
			menus.add(new Menu("Bento", "JP"));
		}
		
		return menus;
	}
	
}

